#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define GGA_LEN		128
#define RTCM_LEN	2048

struct nema
{
	char gga[GGA_LEN];
	char rtcm[RTCM_LEN];
};

struct queue
{
    struct nema * p_nema;
    int front, rear;
    int max_size;
    int deep;
};

void init(struct queue * dest, int max)
{
    int i = 0;

    dest->p_nema = (struct nema *) malloc (sizeof(struct nema) * max);
    if (!dest->p_nema) {
        printf("init malloc fail.\n");
        exit(0);
    }
 
    for (i = 0; i < max; i++) { 
        memset(dest->p_nema[i].gga, 0, GGA_LEN); 
        memset(dest->p_nema[i].rtcm, 0, RTCM_LEN);
    }

    dest->max_size = max;
    dest->front = dest->rear = 0;
    dest->deep = 0;
}

int empty(struct queue * dest)
{
    if (dest->front == dest->rear)
        return 1;
    else
        return 0;
}

int full(struct queue * dest)
{
    if (dest->front == (dest->rear + 1) % dest->max_size) // 判断循环链表是否满，留一个预留空间不用 
        return 1;
    else
        return 0;
}

void enqueue(struct queue * dest, struct nema * src)
{
    if (full(dest)) {
        printf("queue was full.\n");
        return ;
    }

    memcpy(dest->p_nema[dest->rear].gga, src->gga, strlen(src->gga));
    memcpy(dest->p_nema[dest->rear].rtcm, src->rtcm, strlen(src->rtcm)); 
    //dest->queue[dest->rear] = value;
    dest->rear = (dest->rear + 1) % dest->max_size;  // 取余，当dest->rear+1=max_size时，又转回到0.
    dest->deep++;
}

void dequeue(struct queue * dest, struct nema * src)
{
    if (empty(dest)) {
        printf("queue is empty.\n");
        return ;
    }
  
    memcpy(src->gga, dest->p_nema[dest->front].gga, GGA_LEN);
    memcpy(src->rtcm, dest->p_nema[dest->front].rtcm, RTCM_LEN);

    memset(dest->p_nema[dest->front].gga, 0, GGA_LEN);
    memset(dest->p_nema[dest->front].rtcm, 0, RTCM_LEN);

    // dest->queue[dest->front] = -1;
    dest->front = (dest->front + 1) % dest->max_size;
    //dest->front++;
    dest->deep--;
}

void display(struct queue * dest)
{
    int i;
  
    printf("display: -------------------------\n");
    for (i = dest->front; i < dest->max_size; i++) {
        printf("gga[%d]: %s\nrtcm[%d]: %s\n ", 
               i, dest->p_nema[i].gga, i, dest->p_nema[i].rtcm);
    }
    //printf("\n\n");
}

void display_all(struct queue * dest)
{
    int i;
  
    printf("display all: -----------------------\n");
    for (i = 0; i < dest->max_size; i++) {
        printf("gga[%d]: %s\nrtcm[%d]: %s\n ", 
               i, dest->p_nema[i].gga, i, dest->p_nema[i].rtcm);
    }
    //printf("\n\n");
}

void clean(struct queue * dest)
{
    if (dest->p_nema != NULL) {
        free(dest->p_nema);
        dest->p_nema = NULL;
        dest->front = 0;
        dest->rear  = 0;
        dest->max_size = 0;
    }
}

int main()
{
    struct queue queue;
    struct nema p_nema[4] = {0};
    int max_size = 10;

    strcpy(p_nema[0].gga, "$GNGGA 1234.13241,1324134123,E,12");
    strcpy(p_nema[0].rtcm, "d3001473deasdfffdsdfadfadfafasdfa");

    strcpy(p_nema[1].gga, "$GNGGA 1234.13241,1324134123,E,12");
    strcpy(p_nema[1].rtcm, "d3001473deasdfffdsdfadfadfafasdfa");

    strcpy(p_nema[2].gga, "$GNGGA 1234.13241,1324134123,E,12");
    strcpy(p_nema[2].rtcm, "d3001473deasdfffdsdfadfadfafasdfa");

    init(& queue, max_size);
    enqueue(& queue, & p_nema[0]);
    enqueue(& queue, & p_nema[1]);
    enqueue(& queue, & p_nema[1]);
    display(& queue);

    dequeue(& queue, & p_nema[3]);
    display_all(&queue);

    printf("dequeue gga:%s\nrtcm:%s\n",
           p_nema[3].gga, p_nema[3].rtcm);
  



    clean(& queue);
}

